import {
    E2LProtocol,
    L2EProtocol
} from "../proto/ELProtocol";

import {
    gameVersion,
    noticeUrl,
    WX_READY
} from "./CommonUtils";

import {
    NotificationCenter
} from "./NotificationCenter";

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import UpdatePanel from "./UpdatePanel";

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    @property(UpdatePanel)
    Panel: UpdatePanel = null;

    @property(cc.Node)
    UpdateUI: cc.Node = null;

    @property(cc.Asset)
    ManifestUrl: cc.Asset = null;

    private _updating: boolean = false;
    private _canRetry: boolean = false;
    private _storagePath: string = '';

    private _am: jsb.AssetsManager;

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        if (!cc.sys.isNative) {
            // NotificationCenter.Instance.emit(E2LProtocol.e2l_read_configs);
            cc.director.loadScene("Login");
            return;
        }
        this._storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'remote-asset');
        cc.log('Storage path for remote asset : ' + this._storagePath);
        let versionCompareHandle = (versionA, versionB)=>{
            cc.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);
            var vA = versionA.split('.');
            var vB = versionB.split('.');
            for (var i = 0; i < vA.length; ++i) {
                var a = parseInt(vA[i]);
                var b = parseInt(vB[i] || 0);
                if (a === b) {
                    continue;
                } else {
                    return a - b;
                }
            }
            if (vB.length > vA.length) {
                return -1;
            } else {
                return 0;
            }
        };

        // Init with empty manifest url for testing custom manifest
        this._am = new jsb.AssetsManager('', this._storagePath, versionCompareHandle);

        var panel = this.Panel;
        this._am.setVerifyCallback(function (path, asset) {
            var compressed = asset.compressed;
            var expectedMD5 = asset.md5;
            var relativePath = asset.path;
            var size = asset.size;
            if (compressed) {
                panel.info.string = "Verification passed : " + relativePath;
                return true;
            } else {
                panel.info.string = "Verification passed : " + relativePath + ' (' + expectedMD5 + ')';
                return true;
            }
        });

        this.Panel.info.string = '已准备好热更新，请检查或直接更新.';

        if (cc.sys.os === cc.sys.OS_ANDROID) {
            // this._am.setMaxConcurrentTask(2);
            // this.Panel.info.string = "最大并发任务数限制为2";
        }

        this.Panel.fileProgress.progress = 0;
        this.Panel.byteProgress.progress = 0;
        this.checkUpdate(); 
    }

    onDestroy() {
        if (cc.sys.isNative == true) {
        // if (this._updateListener) {
            this._am.setEventCallback(null);
            // this._updateListener = null;
        // }
        }
    }

    start () {
        
    }

    // update (dt) {}
    public onBrn() {
        // if (WX_READY == false) {
        //     // NotificationCenter.Instance.emit(E2LProtocol.e2l_read_configs);
        //     cc.director.loadScene("Hall");
        // } else {
            cc.director.loadScene("Login");
        // }
    }

    public onUpdateClick() {
        this.hotUpdate();
        this.UpdateUI.active = false;
    }

    public onCancelClick() {
        cc.director.pause();
        cc.audioEngine.stopAll();
        if (cc.director.isPaused()) {
            cc.game.end();
        }
    }

    private checkCb(event: any) {
        cc.log('Code: ' + event.getEventCode());
        let isUpdate = false; 
        switch (event.getEventCode()) {
            case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
                this.Panel.info.string = "未找到本地清单文件，已跳过热更新.";
                break;
            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
                this.Panel.info.string = "无法下载清单文件，已跳过热更新.";
                break;
            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
                this.Panel.info.string = "已经是最新远程版本的最新版本.";
                cc.director.loadScene('Login');
                break;
            case jsb.EventAssetsManager.NEW_VERSION_FOUND:
                this.Panel.info.string = '找到新版本，请尝试更新.';
                isUpdate = true ;
                this.Panel.fileProgress.progress = 0;
                this.Panel.byteProgress.progress = 0;
                break;
            default:
                return;
        }

        this._am.setEventCallback(null);
        // this._checkListener = null;
        this._updating = false;

        if (isUpdate) { 
            this.UpdateUI.active = true;
        }
    }

    private updateCb(event:any) {
        var needRestart = false;
        var failed = false;
        switch (event.getEventCode()) {
            case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
                this.Panel.info.string = '未找到本地清单文件，已跳过热更新.';
                failed = true;
                break;
            case jsb.EventAssetsManager.UPDATE_PROGRESSION:
                this.Panel.byteProgress.progress = event.getPercent();
                this.Panel.fileProgress.progress = event.getPercentByFile();

                this.Panel.fileLabel.string = event.getDownloadedFiles() + ' / ' + event.getTotalFiles();
                this.Panel.byteLabel.string = event.getDownloadedBytes() + ' / ' + event.getTotalBytes();

                var msg = event.getMessage();
                if (msg) {
                    this.Panel.info.string = 'Updated file: ' + msg;
                }
                break;
            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
                this.Panel.info.string = '无法下载清单文件，已跳过热更新.';
                failed = true;
                break;
            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
                this.Panel.info.string = '已经是最新的远程版本.';
                failed = true;
                // if(WX_READY == false){
                //     // NotificationCenter.Instance.emit(E2LProtocol.e2l_read_configs);
                //     cc.director.loadScene("Hall");
                // }else{
                    cc.director.loadScene("Login");
                // }
                break;
            case jsb.EventAssetsManager.UPDATE_FINISHED:
                this.Panel.info.string = '更新完成. ' + event.getMessage();
                needRestart = true;
                break;
            case jsb.EventAssetsManager.UPDATE_FAILED:
                this.Panel.info.string = '更新失败. ' + event.getMessage();
                this._updating = false;
                this._canRetry = true;
                break;
            case jsb.EventAssetsManager.ERROR_UPDATING:
                this.Panel.info.string = '资源更新错误: ' + event.getAssetId() + ', ' + event.getMessage();
                break;
            case jsb.EventAssetsManager.ERROR_DECOMPRESS:
                this.Panel.info.string = event.getMessage();
                break;
            default:
                break;
        }

        if (failed) {
            this._am.setEventCallback(null);
            // this._updateListener = null;
            this._updating = false;
        }

        if (needRestart) {
            this._am.setEventCallback(null);
            // this._updateListener = null;
            var searchPaths = jsb.fileUtils.getSearchPaths();
            var newPaths = this._am.getLocalManifest().getSearchPaths();
            console.log(JSON.stringify(newPaths));
            Array.prototype.unshift.apply(searchPaths, newPaths);
            cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
            jsb.fileUtils.setSearchPaths(searchPaths);
            cc.audioEngine.stopAll();
            cc.game.restart();
        }
    }

    private retry() {
        if (!this._updating && this._canRetry) {
            this._canRetry = false;

            this.Panel.info.string = '重试失败 Assets...';
            this._am.downloadFailedAssets();
        }
    }

    private checkUpdate() {
        if (this._updating) {
            this.Panel.info.string = '检查或更新 ...';
            return;
        }
        if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
            // Resolve md5 url
            var url = this.ManifestUrl.nativeUrl;
            if (cc.loader.md5Pipe) {
                url = cc.loader.md5Pipe.transformURL(url);
            }
            this._am.loadLocalManifest(url);
        }
        if (!this._am.getLocalManifest() || !this._am.getLocalManifest().isLoaded()) {
            this.Panel.info.string = '未能加载本地清单 ...';
            return;
        }
        this._am.setEventCallback(this.checkCb.bind(this));

        this._am.checkUpdate();
        this._updating = true;
    }

    private hotUpdate() {
        if (this._am && !this._updating) {
            this._am.setEventCallback(this.updateCb.bind(this));
            if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
                var url = this.ManifestUrl.nativeUrl;
                if (cc.loader.md5Pipe) {
                    url = cc.loader.md5Pipe.transformURL(url);
                }
                this._am.loadLocalManifest(url);
            }

            // this._failCount = 0;
            this._am.update();
            this._updating = true;
        }
    }


}
